package appli.utils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * This class define every constant value we need in the application
 *
 * @author Etienne Sainton
 * @version 0.1
 */
public class Config {
	/**
	 * General configuration
	 * 
	 * active les sorties standart pour les debuggers. il est cependant
	 * recommande d'utiliser la vue debbogage d'Ecplipse pour des problemes Java,
	 * cette focntionnalite est surtout utile pour le SMA
	 */
	public static boolean DEBUG = true;


	/**
	 * To print more informations (agents chat) into the eclipse console
	 */
	public static boolean VERBOSE = true;


	/**
	 * Configuration qui peut agir sur le comportement des agents :
	 * 
	 * Determine le nombre de points disponibles en hauteur (et le double en
	 * alrgeur) dans l'environnement local
	 */
	public static int RESOLUTION = 10;

	/**
	 * Decisive agent perception
	 */
	public static int PERCEPTION = 100;

	/**
	 *  Decisive agent number
	 */
	public static int decisiveAgentNb = 20;

	/**
	 * Define panel height
	 * Width is 2X height
	 */
	public static int PANEL_SIZE = 400;
	
	/**
	 * Define panel config sma sizes
	 */
	public static int PANEL_CONFIG_SMA_SIZE = 300;
	
	 
	/**
	 * Telemeter number
	 * 
	 */
	public static int TELEMETER_NUMBER = 2;
	
	/**
	 * Telemeter port number
	 * 
	 */
	public static List<Integer> TELEMETER_PORT = new ArrayList<Integer>() {{ add(8080); add(8081); add(6502); add(6503); add(6504); }};

	/**
	 * Direction port number
	 */
	public static Integer DIRECTION_PORT = 8082;
	
	/**
	 * Direction Address 
	 */
	public static String DIRECTION_ADDRESS = "172.18.18.222";
	
	/**
	 * Direction Address 
	 */
	public static String TELEMETER_ADDRESS = "localhost";
	
	
	/**
	 * Telemeter perception distance
	 * 
	 */
	public static int TELEMETER_DISTANCE = 8000;

	
	/**
	 * Lance la configuration de l'application
	 */
	public static int TOP_GAP = 200;



	/**
	 * Create or not repulsive agent if two obstacles agents are to far away
	 */
	public static boolean FILL_OBSTACLE_HOLE = true;
	
	/**
	 * Create or not repulsive agent if two obstacles agents are to far away
	 */
	private static final String filePath = "./config/config.xml";


		
	/**
	 * Unity simulator : false
	 * Our "simulator" : true 
	 */
	public static final boolean SIMULATE = true;
	
	/**
	 * 
	 */
	public static SmaConstante SMA_CONSTANTE = new SmaConstante();
	
	/**
	 * 
	 */
	public static SmaConstante SMA_CONSTANTE_PARK = new SmaConstante();
	
	/**
	 * Used to know if the vehicule has to park
	 */
	public static boolean PARK_MODE = false;
	
	/**
	 * 
	 */
	public static void loadConfig(){
		 try {
            // cr�ation d'une fabrique de documents
            DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance();

            // cr�ation d'un constructeur de documents
            DocumentBuilder constructeur = fabrique.newDocumentBuilder();

            // lecture du contenu d'un fichier XML avec DOM
            File xml = new File(filePath);
            if (!xml.exists()) {
                System.err.println("Fichier inexistant.");
            }
            Document document = constructeur.parse(xml);

            NodeList nodes = document.getElementsByTagName("developpement");
            
            if (nodes != null) {
                VERBOSE = 	Boolean.parseBoolean(((Element) nodes.item(0)).getAttribute("verbose"));
                DEBUG = 	Boolean.parseBoolean(((Element) nodes.item(0)).getAttribute("debug"));
            }

            nodes = document.getElementsByTagName("ihm");
            if (nodes != null) {
                RESOLUTION 	= Integer.parseInt(((Element) nodes.item(0)).getAttribute("resolution"));
                PANEL_SIZE = Integer.parseInt(((Element) nodes.item(0)).getAttribute("window_size"));
            }

            nodes = document.getElementsByTagName("multiagent");
            if (nodes != null) {
                PERCEPTION = Integer.parseInt(((Element) nodes.item(0)).getAttribute("perception"));
                decisiveAgentNb = Integer.parseInt(((Element) nodes.item(0)).getAttribute("decisiveAgentNb"));
            }
            
            nodes = document.getElementsByTagName("ihm");
            if (nodes != null) {
                RESOLUTION 	= Integer.parseInt(((Element) nodes.item(0)).getAttribute("resolution"));
                PANEL_SIZE = Integer.parseInt(((Element) nodes.item(0)).getAttribute("window_size"));
            }

            nodes = document.getElementsByTagName("telemeters");
            if (nodes != null) {
            	TELEMETER_ADDRESS = ((Element) nodes.item(0)).getAttribute("address");
            	TELEMETER_NUMBER = Integer.parseInt(((Element) nodes.item(0)).getAttribute("number"));
                TELEMETER_DISTANCE = Integer.parseInt(((Element) nodes.item(0)).getAttribute("telemeter_distance"));
                TOP_GAP = Integer.parseInt(((Element) nodes.item(0)).getAttribute("top_gap"));
                FILL_OBSTACLE_HOLE = Boolean.parseBoolean(((Element) nodes.item(0)).getAttribute("fill_obstacle_hole"));
                
                nodes = document.getElementsByTagName("telemeter");
               
                if (nodes != null) {
                	TELEMETER_PORT = new ArrayList<Integer>();
                	 
                	for(int i=0; i<nodes.getLength(); i++){
                		TELEMETER_PORT.add(Integer.parseInt(((Element) nodes.item(i)).getAttribute("port")));
                	}
                }
            }
            
            nodes = document.getElementsByTagName("car");
            if (nodes != null) {
            	DIRECTION_ADDRESS = ((Element) nodes.item(0)).getAttribute("address");
                DIRECTION_PORT = Integer.parseInt(((Element) nodes.item(0)).getAttribute("port"));

            }
            
            
        } catch (ParserConfigurationException pce) {
            System.out.println("Erreur de configuration du parseur DOM");
            System.out.println("lors de l'appel � fabrique.newDocumentBuilder();");
        } catch (SAXException se) {
            System.out.println("Erreur lors du parsing du document, " + se.getMessage());
            System.out.println("lors de l'appel � construteur.parse(xml)");
        } catch (IOException ioe) {
            System.out.println("Erreur d'entr�e/sortie");
            System.out.println("lors de l'appel � construteur.parse(xml)");
        }
	}
	
}